package cn.com.anypay.manager.service.impl;

import cn.com.anypay.manager.config.AlipayConfig;
import cn.com.anypay.manager.service.UserAuthService;
import cn.com.anypay.manager.common.utils.AlipaySignUtil;
import cn.com.anypay.manager.common.utils.AnyJsonUtils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 支付宝用户授权服务实现类
 */
@Slf4j
@Service
public class AlipayUserAuthServiceImpl implements UserAuthService {
    private static final String AUTH_SCOPE = "auth_base";
    private final RestTemplate restTemplate = new RestTemplate();
    @Override
    public String buildAuthUrl(String appId, String redirectUri) {
        try {
            String encodedRedirectUri = URLEncoder.encode(redirectUri, StandardCharsets.UTF_8.toString());
            return String.format("%s?app_id=%s&scope=%s&redirect_uri=%s",
                    AlipayConfig.OAUTH_URL,
                    appId,
                    AUTH_SCOPE,
                    encodedRedirectUri);
        } catch (Exception e) {
            log.error("构建授权URL失败", e);
            throw new RuntimeException("构建授权URL失败", e);
        }
    }

    @Override
    public Map<String, Object> exchangeAuthCodeForToken(String appId, String authCode, String privateKey) {
        try {
            // 1. 构建请求参数
            Map<String, String> requestParams = new HashMap<>();
            requestParams.put("app_id", appId);
            requestParams.put("method", "alipay.system.oauth.token");
            requestParams.put("charset", "utf-8");
            requestParams.put("sign_type", "RSA2");
            requestParams.put("timestamp", new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            requestParams.put("version", "1.0");
            requestParams.put("grant_type", "authorization_code");
            requestParams.put("code", authCode);

            // 2. 生成签名
            String sign = AlipaySignUtil.generateSign(requestParams, privateKey);
            requestParams.put("sign", sign);

            // 3. 发送请求
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

            // 构建表单数据，对每个参数值进行URL编码
            String formData = requestParams.entrySet().stream()
                .map(entry -> {
                    try {
                        String encodedValue = URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8.toString());
                        return entry.getKey() + "=" + encodedValue;
                    } catch (Exception e) {
                        throw new RuntimeException("URL编码失败", e);
                    }
                })
                .collect(Collectors.joining("&"));

            HttpEntity<String> requestEntity = new HttpEntity<>(formData, headers);
            ResponseEntity<String> responseEntity = restTemplate.exchange(
                AlipayConfig.GATEWAY_URL,
                org.springframework.http.HttpMethod.POST,
                requestEntity,
                String.class
            );
            String response = responseEntity.getBody();
            log.info("支付宝响应: {}", response);

            // 4. 解析响应
            Map<String, Object> result = AnyJsonUtils.toMap(response);
                        Map<String, Object> responseData = AnyJsonUtils.getMapFromObject(
                result.get("alipay_system_oauth_token_response"),
                "alipay_system_oauth_token_response"
            );

            if (responseData != null && responseData.containsKey("user_id")) {
                return responseData;
            } else {
                log.error("获取支付宝授权令牌失败: {}", response);
                throw new RuntimeException("获取支付宝授权令牌失败");
            }
        } catch (Exception e) {
            log.error("获取支付宝授权令牌异常", e);
            throw new RuntimeException("获取支付宝授权令牌异常", e);
        }
    }

    @Override
    public Map<String, Object> getUserProfile(String appId, String accessToken, String privateKey) {
        try {
            // 1. 构建请求参数
            Map<String, String> bizContent = new HashMap<>();
            bizContent.put("auth_token", accessToken);

            Map<String, String> requestParams = new HashMap<>();
            requestParams.put("app_id", appId);
            requestParams.put("method", "alipay.user.info.share");
            requestParams.put("charset", "utf-8");
            requestParams.put("sign_type", "RSA2");
            requestParams.put("timestamp", new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            requestParams.put("version", "1.0");
            requestParams.put("biz_content", AnyJsonUtils.toJsonString(bizContent));

            // 2. 生成签名
            String sign = AlipaySignUtil.generateSign(requestParams, privateKey);
            requestParams.put("sign", sign);

            // 3. 发送请求
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

            // 构建表单数据，对每个参数值进行URL编码
            String formData = requestParams.entrySet().stream()
                .map(entry -> {
                    try {
                        String encodedValue = URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8.toString());
                        return entry.getKey() + "=" + encodedValue;
                    } catch (Exception e) {
                        throw new RuntimeException("URL编码失败", e);
                    }
                })
                .collect(Collectors.joining("&"));

            HttpEntity<String> requestEntity = new HttpEntity<>(formData, headers);
            ResponseEntity<String> responseEntity = restTemplate.exchange(
                AlipayConfig.GATEWAY_URL,
                org.springframework.http.HttpMethod.POST,
                requestEntity,
                String.class
            );
            String response = responseEntity.getBody();
            log.info("支付宝响应: {}", response);

            // 4. 解析响应
            Map<String, Object> result = AnyJsonUtils.toMap(response);
                        Map<String, Object> responseData = AnyJsonUtils.getMapFromObject(
                result.get("alipay_user_info_share_response"),
                "alipay_user_info_share_response"
            );

            if ("10000".equals(responseData.get("code"))) {
                return responseData;
            } else {
                log.error("获取用户信息失败: {}", response);
                throw new RuntimeException("获取用户信息失败: " + responseData.get("sub_msg"));
            }
        } catch (Exception e) {
            log.error("获取用户信息异常", e);
            throw new RuntimeException("获取用户信息异常", e);
        }
    }
}